/*
 * This source code is part of TWaver 4.0
 *
 * Serva Software PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 * Copyright 2002 - 2011 Serva Software. All rights reserved.
 */

package demo.tree.sort;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.ComponentOrientation;
import java.awt.FlowLayout;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.lang.reflect.Field;
import java.util.Comparator;

import javax.swing.ButtonGroup;
import javax.swing.Icon;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;

import twaver.Element;
import twaver.Generator;
import twaver.TDataBox;
import twaver.tree.DataBoxNode;
import twaver.tree.ElementNode;
import twaver.tree.TTree;

public class LanguageSort extends JPanel implements ActionListener{
	
	private static Field fillBackgroundField = null;
	
	static{	
		try {
			fillBackgroundField = DefaultTreeCellRenderer.class.getDeclaredField("fillBackground");
			fillBackgroundField.setAccessible(true);
		} catch (Exception e) {
		}		
	}
	
	private TDataBox box = new TDataBox("Language Sort Demo");
	private ButtonGroup group = new ButtonGroup();
	private JPanel controlPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
	private JCheckBox ascend = new JCheckBox("ASCEND");
	private String sortKey = null;
	private TTree tree = null;
	
	public LanguageSort(){
		super(new BorderLayout());
		
		 tree = new TTree(box) {
			public void prepareRenderer(JLabel renderer, Element element) {
				renderer.setForeground(Color.WHITE);
				renderer.setBackground(new Color(0, 0, 0, 0));
				if (renderer instanceof DefaultTreeCellRenderer) {
					DefaultTreeCellRenderer cellRender = (DefaultTreeCellRenderer) renderer;
					cellRender.setBackgroundNonSelectionColor(null);
				}
				if (fillBackgroundField != null) {
					try {
						fillBackgroundField.setBoolean(renderer, element.isSelected());
					} catch (Exception e) {
					}
				}
			}

			public void paintComponent(Graphics g) {
				this.setOpaque(false);
				Graphics2D g2 = (Graphics2D) g;
				g2.setPaint(new GradientPaint(0, this.getHeight() / 4,
						Color.black, 0, this.getHeight() / 7 * 6, new Color(99,
								130, 191), true));
				g2.fillRect(0, 0, this.getWidth(), this.getHeight());
				super.paintComponent(g);
			}
		};		
		
		this.add(new JScrollPane(tree), BorderLayout.CENTER);
		this.add(controlPanel, BorderLayout.NORTH);
		
		DataFactory.createData(box);
		tree.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
		tree.setElementLabelGenerator(new Generator(){
			public Object generate(Object object) {
				Element element = (Element)object;
				return "<html>" +
						"<font color=blue>" + element.getClientProperty(DataFactory.Language) + "</font> " +
						"<font color=red>P2005:" + element.getClientProperty(DataFactory.PositionDec2005) + "</font> " +
						"<font color=green>P2004:" + element.getClientProperty(DataFactory.PositionDec2004) + "</font> " +
						"<font color=black>R2005:" + element.getClientProperty(DataFactory.RatingsDec2005) + "</font> " +
						"<font color=blue>D2004:" + element.getClientProperty(DataFactory.DeltaDec2004) + "</font> " +
						"<font color=red>Status:" + element.getClientProperty(DataFactory.Status) + "</font> " +
						"</html>";
			}
		});
		
		tree.setElementIconGenerator(new Generator(){
			public Object generate(Object object) {
				Element element = (Element)object;
				final String delta = (String)element.getClientProperty(DataFactory.Delta);
				final Icon deltaIcon = DataFactory.getIcon(delta);
				
				Icon icon = new Icon(){
					public int getIconHeight() {
						return deltaIcon.getIconHeight();
					}
					public int getIconWidth() {
						if(DataFactory.twoIcon(delta)){
							return deltaIcon.getIconWidth() * 2; 
						}else{
							return deltaIcon.getIconWidth(); 
						}
					}
					public void paintIcon(Component c, Graphics g, int x, int y) {
						deltaIcon.paintIcon(c, g, x, y);
						if(DataFactory.twoIcon(delta)){
							x += deltaIcon.getIconWidth();
							deltaIcon.paintIcon(c, g, x, y);
						}
					}
				};
				return icon;
			}
		});
		tree.setRootVisible(false);
		tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
		
		ascend.addActionListener(this);
		controlPanel.add(ascend);
		
		addRadioButton(DataFactory.Delta).setForeground(Color.BLACK);
		addRadioButton(DataFactory.Language).setForeground(Color.BLUE);
		addRadioButton(DataFactory.PositionDec2005).setForeground(Color.RED);
		addRadioButton(DataFactory.PositionDec2004).setForeground(Color.GREEN);
		addRadioButton(DataFactory.RatingsDec2005).setForeground(Color.BLACK);
		addRadioButton(DataFactory.DeltaDec2004).setForeground(Color.BLUE);
		addRadioButton(DataFactory.Status).setForeground(Color.red);
		
		tree.setSortComparator(new Comparator(){
			public int compare(Object o1, Object o2) {
				if(sortKey == null){
					return 0;
				}
				Element e1 = (Element)o1;
				Element e2 = (Element)o2;
				Object v1 = e1.getClientProperty(sortKey);
				Object v2 = e2.getClientProperty(sortKey);
				if(v1 instanceof Comparable && v2 instanceof Comparable){
					Comparable c1 = (Comparable)v1;
					Comparable c2 = (Comparable)v2;
					if(ascend.isSelected()){
						return c1.compareTo(c2);
					}else{
						return -c1.compareTo(c2);
					}
				}
				return 0;
			}
		});
		
        // add element node double click process
        tree.addElementNodeDoubleClickedActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				ElementNode elementNode = (ElementNode)e.getSource();
				String language = (String)elementNode.getElement().getClientProperty(DataFactory.Language);
					JOptionPane.showMessageDialog(tree, 
							"<html><font color=blue>" + language + "</font> is double clicked</html>");
			}
        });
    
        // add box node double click process
        tree.addMouseListener(new MouseAdapter() {
			public void mouseClicked(MouseEvent evt) {
				if (evt.getClickCount() == 2) {
					TreePath path = tree.getPathForLocation(evt.getX(), evt.getY());
					if (path != null) {
						Object comp = path.getLastPathComponent();
						if(comp instanceof DataBoxNode){
							JOptionPane.showMessageDialog(tree, "root node is double clicked");
						}
					}
				}
			}
        });
	}
	
	private JRadioButton addRadioButton(String key){
		JRadioButton button = new JRadioButton(key);
		button.addActionListener(this);
		group.add(button);
		controlPanel.add(button);
		return button;
	}

	public void actionPerformed(ActionEvent e) {
		if(e.getSource() instanceof JRadioButton){
			JRadioButton button = (JRadioButton)e.getSource();
			this.sortKey = button.getText();
		}
		this.tree.updateTViewUI();
	}

}